#include "StdAfx.h"
#include <MyControls/DropDown.h>
#include <MyFC/Utility.h>

namespace My {

// DropDown

DropDown::DropDown()
{
	m_Down.Load("DROPDOWN_BUTTON", "DROPDOWN_BUTTON_MASK");
	VERIFY (m_hCurHandClick = AfxGetApp()->LoadCursor("CURSORHANDCLICK"));
}

void DropDown::Drop()
{
	CMenu menu;
	VERIFY(menu.CreatePopupMenu());

	int index;
	if (!GetCurrent(index))
		index = -1;

	for (My::Size i = 0; i < GetItemCount(); ++i) {
		UINT nFlags = MF_STRING;
		if (int(i) == index)
			nFlags |= MF_CHECKED;
		menu.AppendMenu(nFlags, 1 + i, GetItem(i).c_str());
	}

	CPoint p = ClientToScreen(CPoint(m_DownRect.right, m_DownRect.bottom));

	index =	::TrackPopupMenu(menu.m_hMenu, TPM_RIGHTALIGN|TPM_LEFTBUTTON|TPM_NONOTIFY|TPM_RETURNCMD,
			p.x, p.y, 0, GetWindow()->m_hWnd, 0);
	ReleaseMouse();

	if (index != 0) {
		SetCurrent(index - 1);
		Invalidate();
	}
}

void DropDown::Switch()
{
	int index;
	if (!GetCurrent(index))
		index = 0;
	else
		index = (index + 1) % GetItemCount();

	SetCurrent(index);
	Invalidate();
}

CRect DropDown::CalcTextRect(const String & text)
{
	My::ClientDC dc(this);
	My::SaveObjects save(&dc);

	CRect rClient = ClientRect();
	rClient.right -= 8 + m_Down.Size().cx + 4;

	CRect r(rClient);
	r.InflateRect(-4, 0, -4, 0);

	if (r.IsRectEmpty())
		return r;

	SelectFont(&dc);

	const char * szText = text.empty() ? " " : text.c_str();

	dc.DrawText(szText, &r, DT_SINGLELINE|DT_LEFT|DT_CALCRECT);
	r.OffsetRect(0, (rClient.Height() - r.Height()) / 2);

	r.IntersectRect(&r, &rClient);

	return r;
}

void DropDown::HandlePaint(CDC * pDC, const CRect & r)
{
	My::SaveObjects save(pDC);

	COLORREF cS = GetSysColor(COLOR_BTNSHADOW);
	COLORREF cBlack = RGB(0, 0, 0);

	COLORREF cOld = pDC->GetTextColor();
	int index;
	if (!GetCurrent(index) || !ControlEnabled(this))
		pDC->SetTextColor(cS);
	else
		pDC->SetTextColor(cBlack);

	String s;
	if (index != -1)
		s = GetItem(index);
	else
		s = GetDefaultItem();

	m_TextRect = CalcTextRect(s);

	if (!m_TextRect.IsRectEmpty())
	{
		pDC->DrawText(s.c_str(), &m_TextRect, DT_SINGLELINE|DT_LEFT|DT_VCENTER|DT_END_ELLIPSIS);
	}
	pDC->SetTextColor(cOld);

	if (ControlEnabled(this)) 
	{
		m_DownRect = ClientRect();
		m_DownRect.left = m_DownRect.right - 4 - m_Down.Size().cx - 4;

		if (m_DownRect.Width() < Width()) 
		{
			CPoint p = m_DownRect.CenterPoint();
			m_Down.Draw(pDC, p.x, p.y, My::ALIGN_HCENTER|My::ALIGN_VCENTER);
		}
	}
}

void DropDown::HandleLeftDown(unsigned int flags, const CPoint & p)
{
	Control::HandleLeftDown(flags, p);
	if (!ControlEnabled(this))
		return;
	if (m_DownRect.PtInRect(p))
		Drop();
	if (m_TextRect.PtInRect(p))
		Switch();
}

void DropDown::HandleLeftDoubleClick(unsigned int flags, const CPoint & p)
{
	// Simulate a normal click...
	HandleLeftDown(flags, p);
	Update();
	Sleep(100);
	HandleLeftUp(flags, p);
}

bool DropDown::HandleCursor(unsigned int flags, const CPoint & p)
{
	if ((m_DownRect.PtInRect(p) || m_TextRect.PtInRect(p)) && ControlEnabled(this))
		SetCursor(m_hCurHandClick);
	else
		SetCursor(::LoadCursor(NULL, IDC_ARROW));
	return true;
}

void DropDown::HandleUpdateUI()
{
//	Invalidate();
}

} // My